//
//  UIButtonExtension.swift
//  WalkNovel
//
//  Created by Kevin on 2023/7/4.
//

import UIKit

public enum locationType {
    case top, left, right, bottom
}

extension UIButton {
    /// 设置UIButton内容的位置(图片和文字的位置)
    func layoutButton(style: locationType, imageTitleSpace: CGFloat) {
        //得到imageView和titleLabel的宽高
        let imageWidth = self.imageView?.frame.size.width
        let imageHeight = self.imageView?.frame.size.height
        
        var labelWidth: CGFloat! = 0.0
        var labelHeight: CGFloat! = 0.0
        labelWidth = self.titleLabel?.intrinsicContentSize.width
        labelHeight = self.titleLabel?.intrinsicContentSize.height

        //初始化imageEdgeInsets和labelEdgeInsets
        var imageEdgeInsets = UIEdgeInsets.zero
        var labelEdgeInsets = UIEdgeInsets.zero
        
        //根据style和space得到imageEdgeInsets和labelEdgeInsets的值
        switch style {
        case .top:
            imageEdgeInsets = UIEdgeInsets(top: -labelHeight-imageTitleSpace/2, left: 0, bottom: 0, right: -labelWidth)
            labelEdgeInsets = UIEdgeInsets(top: 0, left: -imageWidth!, bottom: -imageHeight!-imageTitleSpace/2, right: 0)
        case .left:
            imageEdgeInsets = UIEdgeInsets(top: 0, left: -imageTitleSpace/2, bottom: 0, right: imageTitleSpace)
            labelEdgeInsets = UIEdgeInsets(top: 0, left: imageTitleSpace/2, bottom: 0, right: -imageTitleSpace/2)
        case .bottom:
            imageEdgeInsets = UIEdgeInsets(top: 0, left: 0, bottom: -labelHeight!-imageTitleSpace/2, right: -labelWidth)
            labelEdgeInsets = UIEdgeInsets(top: -imageHeight!-imageTitleSpace/2, left: -imageWidth!, bottom: 0, right: 0)
        case .right:
            imageEdgeInsets = UIEdgeInsets(top: 0, left: labelWidth+imageTitleSpace/2, bottom: 0, right: -labelWidth-imageTitleSpace/2)
            labelEdgeInsets = UIEdgeInsets(top: 0, left: -imageWidth!-imageTitleSpace/2, bottom: 0, right: imageWidth!+imageTitleSpace/2)
        }
        self.titleEdgeInsets = labelEdgeInsets
        self.imageEdgeInsets = imageEdgeInsets
    }

    /// 按钮网络图片
    func wn_setupImg(_ img: String?, placeHolder: String?) {
        guard !isBlank(img) else {
            setImage(placeHolder != nil ? UIImage(named: placeHolder!) : nil, for: .normal)
            return
        }
        kf.setImage(with: URL(string: img!), for: .normal, placeholder: placeHolder != nil ? UIImage(named: placeHolder!) : nil, options: nil, progressBlock: nil) { _ in
        }
        kf.setImage(with: URL(string: img!), for: .highlighted, placeholder: placeHolder != nil ? UIImage(named: placeHolder!) : nil, options: nil, progressBlock: nil) { _ in
        }
        kf.setImage(with: URL(string: img!), for: .selected, placeholder: placeHolder != nil ? UIImage(named: placeHolder!) : nil, options: nil, progressBlock: nil) { _ in
        }
    }
    
    /// 按钮背景网络图片
    func wn_setupBackgroundImg(_ img: String?, placeHolder: String?) {
        guard !isBlank(img) else {
            setBackgroundImage(placeHolder != nil ? UIImage(named: placeHolder!) : nil, for: .normal)
            return
        }
        kf.setBackgroundImage(with: URL(string: img!), for: .normal, placeholder: placeHolder != nil ? UIImage(named: placeHolder!) : nil, options: nil, progressBlock: nil) { _ in
        }
        kf.setBackgroundImage(with: URL(string: img!), for: .highlighted, placeholder: placeHolder != nil ? UIImage(named: placeHolder!) : nil, options: nil, progressBlock: nil) { _ in
        }
        kf.setBackgroundImage(with: URL(string: img!), for: .selected, placeholder: placeHolder != nil ? UIImage(named: placeHolder!) : nil, options: nil, progressBlock: nil) { _ in
        }
    }
    
    /// 设置网络图片带过度
    func wn_setupImgFade(_ img: String?, placeHolder: String?) {
        guard !isBlank(img) else {
            setImage(placeHolder != nil ? UIImage(named: placeHolder!) : nil, for: .normal)
            return
        }
        kf.setImage(with: URL(string: img!), for: .normal, placeholder: placeHolder != nil ? UIImage(named: placeHolder!) : nil, options: [ .transition(.fade(1)), .scaleFactor(Screen.scale), .cacheOriginalImage], progressBlock: nil) { _ in
        }
    }
}

// 防止按钮连续点击
public extension UIButton {
    private struct AssociatedKeys {
        static var eventInterval = "eventInterval"
        static var eventUnavailable = "eventUnavailable"
    }
    /// 重复点击的时间 属性设置
    var eventInterval: TimeInterval {
        get {
            if let interval = objc_getAssociatedObject(self, &AssociatedKeys.eventInterval) as? TimeInterval {
                return interval
            }
            return 0.5
        }
        set {
            objc_setAssociatedObject(self, &AssociatedKeys.eventInterval, newValue as TimeInterval, .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
        }
    }
    
    /// 按钮不可点 属性设置
    private var eventUnavailable: Bool {
        get {
            if let unavailable = objc_getAssociatedObject(self, &AssociatedKeys.eventUnavailable) as? Bool {
                return unavailable
            }
            return false
        }
        set {
            objc_setAssociatedObject(self, &AssociatedKeys.eventUnavailable, newValue as Bool, .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
        }
    }
    
    /// 新建初始化方法,在这个方法中实现在运行时方法替换
    class func initializeMethod() {
        let selector = #selector(UIButton.sendAction(_:to:for:))
        let newSelector = #selector(new_sendAction(_:to:for:))
        
        let method: Method = class_getInstanceMethod(UIButton.self, selector)!
        let newMethod: Method = class_getInstanceMethod(UIButton.self, newSelector)!
        if class_addMethod(UIButton.self, selector, method_getImplementation(newMethod), method_getTypeEncoding(newMethod)) {
            class_replaceMethod(UIButton.self, newSelector, method_getImplementation(method), method_getTypeEncoding(method))
        }else {
            method_exchangeImplementations(method, newMethod)
        }
    }
    
    /// 在这个方法中
    @objc private func new_sendAction(_ action: Selector, to target: Any?, for event: UIEvent?) {
        if eventUnavailable == false {
            eventUnavailable = true
            new_sendAction(action, to: target, for: event)
            // 延时
            DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + eventInterval, execute: {
                self.eventUnavailable = false
            })
        }else {
            new_sendAction(action, to: target, for: event)
        }
    }
}
